<?php

/**
 * Diese DAO dient der Kapselung aller Datenbank Oprationen,
 * welche auf dem User basieren.
 * 
 * @author Shane
 * TODO delete($id); delete($username);
 */
class UserDAO extends AbstractDAO {
	
	/**
	 * Der Konstruktor stattet die DAO mit einem DB Objekt aus
	 */
	function __construct() {
		
		parent::__construct('User');
	
		{	// Wenn es die Tabelle nicht gibt, dann soll diese erzeugt werden
			$sql = 'CREATE TABLE IF NOT EXISTS '.User::$tablename.' (
						ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    					Username VARCHAR(30) NOT NULL,
    					Password VARCHAR(32) NOT NULL,
   						Email VARCHAR(100) NOT NULL
   					)';

			$db = DBFactory::getInstance();
			
			// Query vorbereiten
			if (!$stmt = $db->prepare($sql)) {
				// error
				$this->logger->logFile('Database error creating table '.User::$tablename.': '. $db->error, LEVEL_ERROR);
				
				return null;
			}

			// Statement ausführen
			if (!$stmt->execute()) {
				// error
				$this->logger->logFile('Statement error creating table '.User::$tablename.': '. $stmt->error, LEVEL_ERROR);
				
				return null;
			}

			// Statement beenden
			$stmt->close();
			
			unset($db);
		}
	}
	
	/**
	 * Der Destruktor entfernt die Referen auf das DB Objekt
	 */
	function __destruct() {
		parent::__destruct();
	}
	
	/**
	 * Diese Methode liest den Benutzer mit dem Benutzernamen aus der DB
	 * 
	 * @param string $username
	 * @return User wenn vorhanden, sonst null
	 */
	public function getByName($username) {
		$this->handle_previous_error();
		
		// debug
		$this->logger->logFile("Loading User with Username '". $username ."' from database...", LEVEL_DEBUG);
		
		// Lade die Entität mit dem Benutzernamen aus der DB
		$entity = $this->em->getRepository('User')->findBy(array('Username' => $username));
		
		// debug
		$this->logger->logFile($entity ? "Loading User with username '". $username ."' was successfull." : "No User found with username '". $username ."'.", LEVEL_DEBUG);
		
		return $entity;
	}
	
	/**
	 * Diese Methode updated den User, allerdings nur, wenn dieser sich mit dem pw
	 * verifiieren lässt.
	 * 
	 * @param User $user - der User
	 * @param string $password - unhashed old pw
	 * @return UserID wenn erfolgreich, sonst null und Fehler in error
	 */
	public function update($user, $password) {
		$this->handle_previous_error();
		
		// debug
		$this->logger->logFile("Updating User '". $user->get_username() ."'...", LEVEL_DEBUG);
			
		// TODO
		
		// debug
		$this->logger->logFile("User '". $user->get_username() ."' successfully updated.", LEVEL_DEBUG);
		
		// An dieser Stelle ist alles super, deswegen id zurückgeben
		$ret = $user->get_id();
		
		return $ret;
	}
	
	/**
	 * Diese Methode verifiziert einen Username mit einem pw
	 * 
	 * @param string $username
	 * @param string $password unhashed pw
	 * @return UserID, wenn erfolgreich, null falls nicht und Fehler in error
	 */
	public function verify($username, $password) {
		$this->handle_previous_error();
		
		// debug
		$this->logger->logFile("Verifying User '". $username ."'...", LEVEL_DEBUG);
		
		// erstelle das hash
		$hash = md5(md5($username).$password);
		
		// Lade den User mit dem Username und dem PW aus der DB
		$entity = $this->em->getRepository('User')->findBy(array('Username' => $username, 'Password' => $hash));
		
		// debug
		$this->logger->logFile("Successfully verifyed User '". $username ."'", LEVEL_DEBUG);
		
		// Wenn dann sollte nur eine entität vorhanden sein
		if (count($entity) == 1) {
			return $entity[0]->get_id();
		}
		
		return null;
	}

	public function exists($entity) {
		// TODO
	}
	
	public function pre_delete($entity) {
		{// Lösche alle Userrights des Users
			$userrights = DAOFactory::getInstance('Userright')->getByUserId($entity->get_id());
			foreach ($userrights as $userright) {
				DAOFactory::getInstance('Userright')->delete($userright);
			}
		}
	}
}

?>